from datetime import datetime
import logging

import tnetstrings

adm_commands = {
}

def register_cmd(cls):
	"""docstring for register_cmd"""
	adm_commands[cls.path] = cls
#register_cmd()

def get_cmd(path):
	"""docstring for get_cmd"""
	return adm_commands[path]()
#get_cmd()

def check_cmd(path):
	"""docstring for check_cmd"""
	return path in adm_commands
#check_cmd()

#def encode(path, method='GET', params={}, src=0, dst=0):
#	"""return tnetstring for this command
#
#	UUID ID SIZE:PATH,SIZE:METHOD,SIZE:PARAMS}
#	"""
#	#resp = "%s%s" % (tnetstrings.dump(self.path), tnetstrings.dump(self.method))
#	#if self.params:
#	#	resp = "%s%s" % (resp, tnetstrings.dump(self.params))
#		
#	return '%s %s %s%s%s' % (
#			src, dst, tnetstrings.dump(path), 
#			tnetstrings.dump(method), 
#			tnetstrings.dump(params))
##encode()

#def decode(netstr):
#	"""docstring for decode
#
#	UUID ID SIZE:PATH,SIZE:METHOD,SIZE:PARAMS]
#	"""
#
#	logging.debug("decode() netstr : %s" % (netstr,))
#	parts = netstr.split(None, 2)
#
#	resp = {'src': parts[0]}
#	resp['dst'] = parts[1]
#	netstr = parts[2]
#
#	resp['path'], rest = tnetstring.parse(netstr)
#	resp['method'], rest = tnetstring.parse(netstr)
#	params = {}
#	if rest:
#		resp['params'], _ = tnetstring.parse(netstr)
#			
#	return resp
##decode()

class AdmCommand(object):
	"""
	UUID ID SIZE:PATH,SIZE:METHOD,SIZE:PARAMS]

	UUID   : UUID of the sender
	ID     : ID(UUID?) of the target/receiver
	PATH   : The path of the command to run, required.
	METHOD : A restfull method, GET,POST,DELETE,PUT. required, default is GET.
	PARAMS : Command parameters as a dictionary. Optional, default is no params.
	"""

	path = '/default'
	def __init__(self):

		#self.msg = msg

		self._send_log = []
		self._recv_log = []

		self.avl_options = []
		self.methods = ['GET']
		self.method = self.methods = [0]
		self.params = {} 
		#self.params = {'param_name':'accepted regex'}
	#__init__()

	#@property
	#def default_option(self):
	#	"""docstring for default_option"""
	#	return ""
	##default_option()



	def run(self):
		"""docstring for run"""
		raise Exception("run() must be implimented by a subclass")
	#run()

	def verify(self, msg):
		"""docstring for verify"""

		path = msg['path']
		if self.path != path:
			raise NameError("Invalid path : %s, excepted path(s) : %s" % (path, self.path))

		method = msg['method']
		if method.upper() not in self.methods:
			raise ValueError("Method not allowed : %s, excepted methods(s) : %s" % (method, ''))

		params = msg['params']
		for k,v in params.items():
			if k not in self.params:
				raise IndexError("Param not allowed : %s, excepted param(s) : %s" % (params, ''))
	#verify()


	def __repr__(self):
		"""docstring for __repr__"""
		return "Path : %s\nMethods : %s\nParams : %s" % (
				self.path, self.methods, self.params )
	#__repr__()

	#def __str__(self):
	#	return self.__str__()
	##__str__()
#AdmCommand

class AdmCmdPing(AdmCommand):
	"""
	UUID ID CMD:
	"""

	path = "/ping"
	def __init__(self):
		super(AdmCmdPing, self).__init__()

		self.ping_start_time = datetime.now()

		self.methods = ['GET']
	#__init__()
#AdmCmdPing
register_cmd(AdmCmdPing)

class AdmCmdStatus(AdmCommand):
	"""docstring for AdmCmdStatus"""

	path = "/status"
	def __init__(self):
		super(AdmCmdStatus, self).__init__()

		self.avl_options = ['min','normal','max'] 
	#__init__()

	#@property
	#def default_option(self):
	#	return self.options[1]
	##default_option()
#AdmCmdStatus
register_cmd(AdmCmdStatus)

